package juego.constructorDeNiveles;

import java.util.Random;

import obstrucciones.Obstruccion;
import obstrucciones.obstaculos.ControlPolicial;
import obstrucciones.obstaculos.Piquete;
import obstrucciones.obstaculos.Pozo;
import obstrucciones.sorpresas.CambioDeVehiculo;
import obstrucciones.sorpresas.SorpresaDesfavorable;
import obstrucciones.sorpresas.SorpresaFavorable;
import ciudad.Calle;
import ciudad.Ciudad;
import ciudad.Esquina;

public class DispersorDeObstrucciones {
	
	Ciudad ciudadADispersar;
	
	public DispersorDeObstrucciones(Ciudad ciudad) {
		ciudadADispersar = ciudad;
	}
	
	/* Devuelve la ciudad donde se dispersaran las obstrucciones.*/
	public Ciudad getCiudad() {
		return this.ciudadADispersar;
	}
	
	//Devuelve una calle al azar de una esquina posicionada
	//en las coordenadas recibidas.
	//Pre: Recibe la posicion de la esquina en la forma (indiceFila, indiceColumna).
	//Post: Se devolve alguna calle de la esquina (Puede ser null).
	 public Calle getCalleAlAzarDeEsquina(int posicionFila, int posicionColumna) {
		Ciudad ciudad = this.getCiudad();
		Esquina esquina = ciudad.getEsquinaEnPosicion(posicionFila, posicionColumna);
		int cantidadDeCalles = 4;
		
		//Se selecciona un natural al azar entre 0 y 4(exclusive)
		//Dependiendo del n�mero aleatorio se devuelve la calle correspondiente.
		Random random = new Random();
		int numeroAleatorio = random.nextInt(cantidadDeCalles);
		
		switch (numeroAleatorio) {
		case 0:
			return esquina.getCalleNorte();
		case 1:
			return esquina.getCalleOeste();
		case 2:
			return esquina.getCalleSur();
		case 3:
			return esquina.getCalleEste();
		default:
			return null;
		}
	}

	//Agrega una obstruccion en una calle de la ciudad al azar.
	//Pre: Recibe una obstruccion.
	//Post: Se asigna a alguna calle de la ciudad una nueva obstruccion.
	public void agregarObstruccionEnCalleAlAzar(Obstruccion obstruccion) {
		Ciudad ciudad = this.getCiudad();
		int cantidadCallesVerticales = ciudad.getCantidadDeCallesVerticales();
		int cantidadCallesHorizontales = ciudad.getCantidadDeCallesHorizontales();
		
		//Se genera una posicion en forma aleatoria.
		Random randFila = new Random();
		Random randColumna = new Random();
		
		int indiceFila = randFila.nextInt(cantidadCallesHorizontales);
		int indiceColumna = randColumna.nextInt(cantidadCallesVerticales);
		
		Calle calleAleatoria = this.getCalleAlAzarDeEsquina(indiceFila, indiceColumna);
		calleAleatoria.agregarObstruccion(obstruccion);
	}
	
	//Dispersa las obstrucciones de tipo Pozo en la ciudad.
	//La cantidad de Pozos dispersados sigue la regla:
	//Cantidad = cantidad de calles verticales en Ciudad / 2.
	public void dispersarPozosEnCiudad() {
		Ciudad ciudad = this.getCiudad();
		int cantidadCallesVerticales = ciudad.getCantidadDeCallesVerticales();
		int cantidadDePozos = cantidadCallesVerticales / 2 ;
		
		for (int numeroDePozo = 1; numeroDePozo <= cantidadDePozos; numeroDePozo++) {
			Pozo pozo = new Pozo();
			this.agregarObstruccionEnCalleAlAzar(pozo);
		}
	}
	
	//Dispersa las obstrucciones de tipo Piquete en la ciudad.
	//La cantidad de Piquetes dispersados sigue la regla:
	//Cantidad = (cantidad de calles horizontales en Ciudad + 2) / 2.
	public void dispersarPiquetesEnCiudad() {
		Ciudad ciudad = this.getCiudad();
		int cantidadCallesHorizontales = ciudad.getCantidadDeCallesHorizontales();
		int cantidadDePiquetes = (cantidadCallesHorizontales + 2) / 2;
		
		for (int numeroDePiquete = 1; numeroDePiquete <= cantidadDePiquetes; numeroDePiquete++) {
			Piquete piquete = new Piquete();
			this.agregarObstruccionEnCalleAlAzar(piquete);
		}
	}
	
	//Dispersa las obstrucciones de tipo ControlPolicial en la ciudad.
	//La cantidad de Controles Policiales dispersados sigue la regla:
	//Cantidad = (cantidad de calles verticales en Ciudad + 2) /2.
	public void dispersarControlesPolicialesEnCiudad() {
		Ciudad ciudad = this.getCiudad();
		int cantidadCallesVerticales = ciudad.getCantidadDeCallesVerticales();
		int cantidadDePolicias = (cantidadCallesVerticales + 2) / 2;
		
		for (int numeroDePolicia = 1; numeroDePolicia <= cantidadDePolicias; numeroDePolicia++) {
			ControlPolicial policia = new ControlPolicial();
			this.agregarObstruccionEnCalleAlAzar(policia);
		}
	}	
	
	//Dispersa las obstrucciones de tipo SorpresaFavorable en la ciudad.
	//La cantidad de Sorpresas Favorables dispersadas sigue la regla:
	//Cantidad = (cantidad de calles horizontales en Ciudad) / 3.
	public void dispersarSorpresasFavorablesEnCiudad() {
		Ciudad ciudad = this.getCiudad();
		int cantidadCallesHorizontales = ciudad.getCantidadDeCallesHorizontales();
		int cantidadDeSorpresas = cantidadCallesHorizontales / 3;
		
		for (int numeroDeSorpresa = 1; numeroDeSorpresa <= cantidadDeSorpresas; numeroDeSorpresa++) {
			SorpresaFavorable sorpresa = new SorpresaFavorable();
			this.agregarObstruccionEnCalleAlAzar(sorpresa);
		}
	}

	//Dispersa las obstrucciones de tipo SorpresaDesfavorable en la ciudad.
	//La cantidad de Sorpresas Desfavorables dispersadas sigue la regla:
	//Cantidad = (cantidad de calles verticales en Ciudad + 3) / 2.
	public void dispersarSorpresasDesfavorablesEnCiudad() {
		Ciudad ciudad = this.getCiudad();
		int cantidadCallesVerticales = ciudad.getCantidadDeCallesVerticales();
		int cantidadDeSorpresas = (cantidadCallesVerticales + 3)/ 2;
		
		for (int numeroDeSorpresa = 1; numeroDeSorpresa <= cantidadDeSorpresas; numeroDeSorpresa++) {
			SorpresaDesfavorable sorpresa = new SorpresaDesfavorable();
			this.agregarObstruccionEnCalleAlAzar(sorpresa);
		}
	}	
	
	//Dispersa las obstrucciones de tipo CambioDeVehiculo en la ciudad.
	//La cantidad de Cambios de Vehiculo dispersadas sigue la regla:
	//Cantidad = (cantidad de calles verticales en Ciudad) / 2.
	public void dispersarCambiosDeVehiculoEnCiudad() {
		Ciudad ciudad = this.getCiudad();
		int cantidadCallesVerticales = ciudad.getCantidadDeCallesVerticales();
		int cantidadDeCambios = (cantidadCallesVerticales - 3) / 2;
		
		for (int numeroDeCambio = 1; numeroDeCambio <= cantidadDeCambios; numeroDeCambio++) {
			CambioDeVehiculo cambio = new CambioDeVehiculo();
			this.agregarObstruccionEnCalleAlAzar(cambio);
		}
	}

	//Dispersa todas las obstrucciones posibles
	//segun la regla impuesta por cada obstruccion particular.
	public void dispersarTodasLasObstrucciones() {
		this.dispersarPozosEnCiudad();
		this.dispersarPiquetesEnCiudad();
		this.dispersarControlesPolicialesEnCiudad();
		this.dispersarSorpresasFavorablesEnCiudad();
		this.dispersarSorpresasDesfavorablesEnCiudad();
		this.dispersarCambiosDeVehiculoEnCiudad();
	}
}
